package com.kxmall.common.helper;

import cn.dev33.satoken.stp.StpUtil;
import com.kxmall.common.core.domain.model.LoginUser;
import com.kxmall.common.enums.DeviceType;
import com.kxmall.common.enums.UserType;
import com.kxmall.common.exception.ServiceException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 用户身份验证助手
 * 用于防止用户和骑手登录串号问题
 *
 * @author kxmall
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class UserIdentityHelper {

    /**
     * 验证并获取APP用户信息（安全版本）
     * 确保当前登录用户是APP用户类型，防止ThreadLocal污染
     */
    public static LoginUser getVerifiedAppUser() {
        // 使用安全方法获取用户信息，跳过ThreadLocal缓存
        LoginUser loginUser = LoginHelper.getLoginUserFromToken();
        if (loginUser == null) {
            throw new ServiceException("用户未登录");
        }

        // 验证用户类型
        if (!UserType.APP_USER.getUserType().equals(loginUser.getUserType())) {
            log.warn("用户类型不匹配 - 期望: {}, 实际: {}, 用户ID: {}",
                UserType.APP_USER.getUserType(), loginUser.getUserType(), loginUser.getUserId());
            throw new ServiceException("用户类型不正确");
        }

        // 验证设备类型
        DeviceType currentDevice = LoginHelper.getDeviceType();
        if (!DeviceType.APP.equals(currentDevice)) {
            log.warn("设备类型不匹配 - 期望: {}, 实际: {}, 用户ID: {}",
                DeviceType.APP, currentDevice, loginUser.getUserId());
            throw new ServiceException("设备类型不正确");
        }

        // 验证LoginId格式
        String expectedLoginId = UserType.APP_USER.getUserType() + LoginHelper.JOIN_CODE + loginUser.getUserId();
        String actualLoginId = StpUtil.getLoginIdAsString();
        if (!expectedLoginId.equals(actualLoginId)) {
            log.error("LoginId不匹配 - 期望: {}, 实际: {}, 用户ID: {}",
                expectedLoginId, actualLoginId, loginUser.getUserId());
            throw new ServiceException("用户身份验证失败");
        }

        return loginUser;
    }

    /**
     * 验证并获取骑手用户信息（安全版本）
     * 确保当前登录用户是骑手类型，防止ThreadLocal污染
     */
    public static LoginUser getVerifiedRiderUser() {
        // 使用安全方法获取用户信息，跳过ThreadLocal缓存
        LoginUser loginUser = LoginHelper.getLoginUserFromToken();
        if (loginUser == null) {
            throw new ServiceException("骑手未登录");
        }

        // 验证用户类型
        if (!UserType.RIDER_USER.getUserType().equals(loginUser.getUserType())) {
            log.warn("骑手类型不匹配 - 期望: {}, 实际: {}, 骑手ID: {}",
                UserType.RIDER_USER.getUserType(), loginUser.getUserType(), loginUser.getUserId());
            throw new ServiceException("骑手类型不正确");
        }

        // 验证设备类型
        DeviceType currentDevice = LoginHelper.getDeviceType();
        if (!DeviceType.RIDER.equals(currentDevice)) {
            log.warn("设备类型不匹配 - 期望: {}, 实际: {}, 骑手ID: {}",
                DeviceType.RIDER, currentDevice, loginUser.getUserId());
            throw new ServiceException("设备类型不正确");
        }

        // 验证LoginId格式
        String expectedLoginId = UserType.RIDER_USER.getUserType() + LoginHelper.JOIN_CODE + loginUser.getUserId();
        String actualLoginId = StpUtil.getLoginIdAsString();
        if (!expectedLoginId.equals(actualLoginId)) {
            log.error("LoginId不匹配 - 期望: {}, 实际: {}, 骑手ID: {}",
                expectedLoginId, actualLoginId, loginUser.getUserId());
            throw new ServiceException("骑手身份验证失败");
        }

        return loginUser;
    }

    /**
     * 记录登录成功日志
     */
    public static void logLoginSuccess(LoginUser loginUser, DeviceType deviceType, String tokenPrefix) {
        log.info("登录成功 - 用户类型: {}, 用户ID: {}, 设备类型: {}, Token前缀: {}, OpenId: {}", 
            loginUser.getUserType(), 
            loginUser.getUserId(), 
            deviceType, 
            tokenPrefix,
            loginUser.getOpenId() != null ? loginUser.getOpenId().substring(0, Math.min(10, loginUser.getOpenId().length())) + "..." : "null");
    }

    /**
     * 记录业务操作日志
     */
    public static void logBusinessOperation(String operation, LoginUser loginUser, String... params) {
        log.info("业务操作 - 操作: {}, 用户类型: {}, 用户ID: {}, 设备类型: {}, 参数: {}", 
            operation,
            loginUser.getUserType(), 
            loginUser.getUserId(), 
            LoginHelper.getDeviceType(),
            params != null ? String.join(",", params) : "无");
    }

    /**
     * 检查是否存在潜在的串号风险
     */
    public static void checkCrossAccountRisk(String openId, UserType userType, Long userId) {
        // 这里可以添加更复杂的串号检测逻辑
        // 比如检查同一openId是否在短时间内登录了不同类型的账户
        log.debug("串号风险检查 - OpenId: {}, 用户类型: {}, 用户ID: {}", 
            openId != null ? openId.substring(0, Math.min(10, openId.length())) + "..." : "null", 
            userType, 
            userId);
    }
}
